//=======================================================================//
//= Include files.													    =//
//=======================================================================//
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/msgdlg.h>
#include <wx/filedlg.h>
#include "VectorString.h"
#include "ControlID.h"
#include "FontToolWindow.h"
#include "GeneralToolBar.h"
#include "FontToolBar.h"
#include "Settings.h"
#include "Utility.h"

//=======================================================================//
//= Global variable define.											    =//
//=======================================================================//
const wxString PIXEL_FONT_WINDOW_NAME = wxT("Font Window");

//=======================================================================//
//= Event table.													    =//
//=======================================================================//
BEGIN_EVENT_TABLE(FontToolWindow, sptChildWindowBase)
	EVT_PAINT_FONT(EVT_PAINT_FONT_CHANGED,		FontToolWindow::OnFontChanged)
	EVT_BUTTON(ID_CTRL_OPEN_FILE,				FontToolWindow::OnOpenFile)
	EVT_BUTTON(ID_CTRL_DEDUPLICATION,			FontToolWindow::OnDeduplication)
    EVT_BUTTON(ID_CTRL_SORT,					FontToolWindow::OnReorder)
    EVT_BUTTON(ID_TOOL_SAVE_FILE,				FontToolWindow::OnSaveFile)
END_EVENT_TABLE()

//=======================================================================//
//= Function define.										            =//
//=======================================================================//
FontToolWindow::FontToolWindow(wxAuiMDIParentFrame * pclsParent)
: sptChildWindowBase(pclsParent, wxID_ANY, PIXEL_FONT_WINDOW_NAME)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxBoxSizer*				pclsRootSizer = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer*             pclsInputSizer = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer*             pclsOutputSizer = new wxBoxSizer(wxVERTICAL);

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	pclsRootSizer->Add(pclsInputSizer, 1, wxEXPAND|wxRIGHT, 5);
    pclsRootSizer->Add(pclsOutputSizer, 0, wxEXPAND, 5);

    // Input area.
    {
        m_pclsTextEditor = new wxTextCtrl( this, ID_CTRL_TEXT_EDITOR, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE/*|wxTE_READONLY*/);
        m_pclsTextEditor->SetFont(GlobalPaintFont().Font());
        pclsInputSizer->Add(m_pclsTextEditor, 1, wxEXPAND, 5);
    }

	// Option area.
	{
	    {
	        wxStaticBoxSizer* pclsOutputOptionSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Options"));
	        m_pclsOpenFileButton = new wxButton(pclsOutputOptionSizer->GetStaticBox(), ID_CTRL_OPEN_FILE, wxT("Open File"));
            m_pclsOpenFileButton->SetBitmap(wxBITMAP_PNG(RES_ID_BMP_BUTTON_IMAGE_OPEN_FILE));
            m_pclsDeduplicationButton = new wxButton( pclsOutputOptionSizer->GetStaticBox(), ID_CTRL_DEDUPLICATION, wxT("Deduplication"), wxDefaultPosition, wxDefaultSize, 0 );
            m_pclsDeduplicationButton->SetBitmap(wxBITMAP_PNG(RES_ID_BMP_BUTTON_IMAGE_DEDUPLICATION));
            m_pclsReorderButton = new wxButton( pclsOutputOptionSizer->GetStaticBox(), ID_CTRL_SORT, wxT("Reorder"), wxDefaultPosition, wxDefaultSize, 0 );
            m_pclsReorderButton->SetBitmap(wxBITMAP_PNG(RES_ID_BMP_BUTTON_IMAGE_REORDER));

            pclsOutputOptionSizer->Add(m_pclsOpenFileButton, 0, wxALL|wxEXPAND, 5);
            pclsOutputOptionSizer->Add(m_pclsDeduplicationButton, 0, wxALL|wxEXPAND, 5);
            pclsOutputOptionSizer->Add(m_pclsReorderButton, 0, wxALL|wxEXPAND, 5);

            pclsOutputSizer->Add(pclsOutputOptionSizer, 1, wxEXPAND, 5);
	    }

	    {
            wxStaticBoxSizer* pclsOutputFileSizer = new wxStaticBoxSizer(wxVERTICAL, this, CFG_XML_NODE_NAME_OUTPUT);

            wxBoxSizer* pclsOutputPathSizer = new wxBoxSizer( wxHORIZONTAL );
            m_pclsOutputFilePathText = new wxTextCtrl(pclsOutputFileSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
            m_pclsSelectOutputButton = new wxBitmapButton(pclsOutputFileSizer->GetStaticBox(), ID_TOOL_SAVE_FILE, wxBITMAP_PNG(RES_ID_BMP_BUTTON_IMAGE_SAVE_TO_FILE));
            pclsOutputPathSizer->Add(m_pclsOutputFilePathText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
            pclsOutputPathSizer->Add(m_pclsSelectOutputButton, 0, wxALL, 5 );
            pclsOutputFileSizer->Add(pclsOutputPathSizer, 1, wxEXPAND, 5);

            m_pclsBinaryCheck = new wxCheckBox(pclsOutputFileSizer->GetStaticBox(), wxID_ANY, wxT("Output in binary"), wxDefaultPosition, wxDefaultSize, 0 );
            pclsOutputFileSizer->Add(m_pclsBinaryCheck, 0, wxALL|wxEXPAND, 5 );

            pclsOutputSizer->Add( pclsOutputFileSizer, 0, wxEXPAND, 5 );
	    }
	}

	SetSizer( pclsRootSizer );
	Layout();

	m_pclsOutputTextFile = nullptr;
	m_pclsParentFrame = pclsParent;
}

FontToolWindow::~FontToolWindow(void)
{
    /* Do nothing */
}

void FontToolWindow::OnFontChanged(wxCommandEvent& clsEvent)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(nullptr != m_pclsTextEditor)
	{
		m_pclsTextEditor->SetFont(GlobalPaintFont().Font());
	}
	clsEvent.StopPropagation();
}

void FontToolWindow::OnSettingChanged(wxCommandEvent& clsEvent)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	clsEvent.StopPropagation();
}

void FontToolWindow::OnOpenFile(wxCommandEvent& clsEvent)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxFileDialog			clsOpenFileDialog(this, wxT("Open text file."), wxEmptyString, wxEmptyString,
										wxT("Text file (*.txt)|*.txt|C source (*.c)|*.c|C++ source(*.cpp)|*.cpp|C++ source(*.cxx)|*.cxx|Binary(*.bin)|*.bin|All files (*.*)|*.*"),
										wxFD_OPEN|wxFD_FILE_MUST_EXIST);
	wxTextFile				clsInputFile;
	wxString                strTextContent;

	/*----------------------------------*/
	/* Initialize						*/
	/*----------------------------------*/
	strTextContent.Clear();
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
    if(wxID_OK == clsOpenFileDialog.ShowModal())
    {
        if(true == clsInputFile.Open(clsOpenFileDialog.GetPath(), wxConvAuto(wxFONTENCODING_UTF8)))
        {
            m_pclsTextEditor->Clear();
            strTextContent.Append(clsInputFile.GetFirstLine());
            strTextContent.Append('\n');
            for(size_t sLineIdx=1; sLineIdx<clsInputFile.GetLineCount(); sLineIdx++)
            {
                strTextContent.Append(clsInputFile.GetNextLine());
                strTextContent.Append(wxT('\n'));
            }
            m_pclsTextEditor->SetValue(strTextContent);
        }
    }

	clsEvent.Skip();
	clsEvent.StopPropagation();
}

void FontToolWindow::OnDeduplication(wxCommandEvent& clsEvent)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxVectorString          clsStrVector(m_pclsTextEditor->GetValue());
	wxString                strProcessedString;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	clsStrVector.Deduplication();
	clsStrVector.Remove('\n');
	clsStrVector.Remove('\r');
	clsStrVector.Remove('\t');
    clsStrVector.ToString(strProcessedString);
	m_pclsTextEditor->SetValue(strProcessedString);

	clsEvent.Skip();
	clsEvent.StopPropagation();
}

void FontToolWindow::OnReorder(wxCommandEvent& clsEvent)
{
    /*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxVectorString          clsStrVector(m_pclsTextEditor->GetValue());
	wxString                strProcessedString;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	clsStrVector.Sort();
    clsStrVector.ToString(strProcessedString);
	m_pclsTextEditor->SetValue(strProcessedString);

	clsEvent.Skip();
	clsEvent.StopPropagation();
}

void FontToolWindow::OnSaveFile(wxCommandEvent& clsEvent)
{
    /*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxFileDialog			clsSaveFileDialog(this, wxT("Save text file."), wxEmptyString, wxEmptyString,
										wxT("Text file (*.txt)|*.txt|All files (*.*)|*.*"), wxFD_SAVE);

	/*----------------------------------*/
	/* Initialize						*/
	/*----------------------------------*/

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
    if(wxID_OK == clsSaveFileDialog.ShowModal())
    {
        m_pclsOutputFilePathText->SetValue(clsSaveFileDialog.GetPath());
    }

	clsEvent.Skip();
	clsEvent.StopPropagation();
}

wxString FontToolWindow::GetInput(void) const
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	return m_pclsTextEditor->GetValue();
}

bool FontToolWindow::OnPrepareStart(void)
{
    /*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	bool                    bReturn;

	/*----------------------------------*/
	/* Initialize						*/
	/*----------------------------------*/
	bReturn =               true;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/

    if(nullptr == m_pclsOutputTextFile)
    {
        m_pclsOutputTextFile = new wxFile();
    }
    m_pclsOutputTextFile->Create(m_pclsOutputFilePathText->GetValue(), true, wxS_DEFAULT);
    bReturn = m_pclsOutputTextFile->Open(m_pclsOutputFilePathText->GetValue(), wxFile::write);
    if(false == bReturn)
    {
        wxMessageBox(wxString::Format(wxT("Cannot open file %s."), m_pclsOutputFilePathText->GetValue()), wxT("Error"), wxOK|wxCENTER|wxICON_ERROR);
    }

	return bReturn;
}

bool FontToolWindow::OnProcessDone(void)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
    m_pclsOutputTextFile->Close();
    delete m_pclsOutputTextFile;
    m_pclsOutputTextFile = nullptr;
	return true;
}

